﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Collections;

namespace MetMax
{
    public partial class MainForm : Form
    {
        /// <summary>
        /// holds a dummy of the BusinesObject, so the ouput of all the objects cann be controlles by a internal static variable accross all instances
        /// </summary>
        private BusinessObject.Base DummyBusinessObject = new BusinessObject.Base(MetMax.Properties.Settings.Default.myOptions);

        public MainForm()
        {
            InitializeComponent();
            if (Properties.Settings.Default.myOptions == null)
            {
                Properties.Settings.Default.myOptions = new Options();
                Properties.Settings.Default.Save();
            }
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
            cbDisplay.SelectedIndexChanged -= new EventHandler(cbDisplay_SelectedIndexChanged);
            cbDisplay.Items.AddRange(Enum.GetNames(typeof(DisplayProperties)).ToArray());
            cbDisplay.SelectedIndex = cbDisplay.FindStringExact(Enum.GetName(typeof(DisplayProperties), Properties.Settings.Default.myOptions.exportFact));
            cbDisplay.SelectedIndexChanged += new EventHandler(cbDisplay_SelectedIndexChanged);
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            Properties.Settings.Default.Save();
            base.OnClosing(e);
        }

        private void button1_Click_start(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                progressBar.Value = 0;
                progressBar.Maximum = openFileDialog1.FileNames.Length;

                button1.Text = "cancel";
                button1.Click -= new EventHandler(button1_Click_start);
                button1.Click += new EventHandler(button1_Click_cancel);

                status.Text = string.Format("{0} file(s) selected", openFileDialog1.FileNames.Length);

                //create the arguments for the backGroundWorker
                Importer.BackgroundWorkerArgument bgwa = new Importer.BackgroundWorkerArgument { dt = null, filenames = openFileDialog1.FileNames };
                if (((dgv_result.DataSource as BindingSource) != null) && (((dgv_result.DataSource as BindingSource).DataSource as DataTable) != null))
                {
                    bgwa.dt = (dgv_result.DataSource as BindingSource).DataSource as DataTable;
                }

                Importer.Base importer = null;
                switch (Properties.Settings.Default.myOptions.Importer_version)
                {
                    case Options.ImporterVersion.RetentionAnalysis:
                        importer = new Importer.RetentionAnalysis(bgwa, Properties.Settings.Default.myOptions);
                        break;
                    case Options.ImporterVersion.IsotopeConcentrator:
                        importer = new Importer.IsotopeConcentrator(bgwa, Properties.Settings.Default.myOptions);
                        break;
                    case Options.ImporterVersion.LibrarySearch:
                        importer = new Importer.LibrarySearch(bgwa, Properties.Settings.Default.myOptions);
                        break;
                    default:
                        throw new NotImplementedException();
                }
                importer.ProgressChanged += new ProgressChangedEventHandler(bgw_importer_ProgressChanged);
                importer.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_importer_RunWorkerCompleted);

                //register a method to close the cancelForm
                //gmdTools.CancelForm frmCancel = new gmdTools.CancelForm(importer);
                //importer.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(frmCancel.WorkerCompleted);
                //frmCancel.CancelEvent += new EventHandler<EventArgs>(frmCancel_CancelEventRaised);

                importer.RunWorkerAsync(bgwa);
                //frmCancel.ShowDialog();
            }
            else
            {
                status.Text = "no files selected";
            }
        }

        private void frmCancel_CancelEventRaised(object sender, EventArgs e)
        {
            status.Text = "cancelation pending";
        }


        private void button1_Click_cancel(object sender, EventArgs e)
        {
            button1.Text = "start";
            button1.Click -= new EventHandler(button1_Click_cancel);
            button1.Click += new EventHandler(button1_Click_start);
        }

        private void bgw_importer_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            Importer.ProgressReportObject res = e.UserState as Importer.ProgressReportObject;

            BindingSource bs = new BindingSource();
            bs.DataSource = res.dt;
            dgv_result.DataSource = bs;

            status.Text = string.Format("processing of '{0}' finished", res.filename);
        }

        private void bgw_importer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            button1_Click_cancel(null, null);

            if (((dgv_result.DataSource as BindingSource) != null) && (((dgv_result.DataSource as BindingSource).DataSource as DataTable) != null))
            {
                //finalise the table
                if ((dgv_result.DataSource as BindingSource).DataSource is MetMaxDataSet.resultDataTable)
                {
                    ((dgv_result.DataSource as BindingSource).DataSource as MetMaxDataSet.resultDataTable).finish();
                }
                else if ((dgv_result.DataSource as BindingSource).DataSource is MetMaxDataSet.result_LibrarySearchDataTable)
                {
                    ((dgv_result.DataSource as BindingSource).DataSource as MetMaxDataSet.result_LibrarySearchDataTable).finish();
                }

                sortColumns(dgv_result);

                if (e.Cancelled)
                {
                    status.Text = string.Format("canceled");
                }
                else
                {
                    //status.Text = string.Format("finished, dataset with {0} processed file(s) and {1} items", dt.Columns.Count > 3 ? dt.Columns.Count - dt.MasterColumnCount() : 0, dt.Rows.Count);
                }
            }
            else
            {
                status.Text = string.Format("no valid data found in {0} file(s)", openFileDialog1.FileNames.Length);
            }

            progressBar.Value = 0;
        }

        private void sortColumns(DataGridView dgv)
        {
            //if (((dgv_result.DataSource as BindingSource) != null) && (((dgv_result.DataSource as BindingSource).DataSource as DataTable) != null))
            //{
            //    DataTable_Base dt = (dgv_result.DataSource as BindingSource).DataSource as DataTable_Base;
            //    //all adding is finished here, so lets start sorting the columns

            //    IEnumerable<string> cols = from colname in dt.ResultColumnNames()
            //                               orderby colname ascending
            //                               select colname;

            //    List<string> resultColumns = cols.ToList();

            //    int MasterColumnCount = dt.MasterColumnCount();
            //    foreach (string s in resultColumns)
            //    {
            //        dgv_result.Columns[s].DisplayIndex = MasterColumnCount++;
            //    }
            //}
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (((dgv_result.DataSource as BindingSource) != null) && (((dgv_result.DataSource as BindingSource).DataSource as DataTable) != null))
            {
                DataTable dt = ((dgv_result.DataSource as BindingSource).DataSource as DataTable);
                dgv_result.DataSource = null;
                dt.Dispose();
                status.Text = string.Format("new dataset created");
            }
            else
            {
                status.Text = string.Format("dataset is already empty");
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            Application.Exit();
        }

        #region Open & Save
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.UseWaitCursor = true;
            Stream myStream;
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*";
            saveFileDialog.FilterIndex = 0;
            saveFileDialog.RestoreDirectory = true;

            if (((dgv_result.DataSource as BindingSource) != null) && (((dgv_result.DataSource as BindingSource).DataSource as DataTable) != null))
            {
                DataTable dt = (dgv_result.DataSource as BindingSource).DataSource as DataTable;

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    if ((myStream = saveFileDialog.OpenFile()) != null)
                    {
                        dt.DataSet.WriteXml(myStream);
                        myStream.Close();
                        status.Text = string.Format("dataset saved into file '{0}'", saveFileDialog.FileName);
                    }
                }
            }
            else
            {
                status.Text = string.Format("nothing to save");
            }

            Application.UseWaitCursor = false;
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*";
            openFileDialog.FilterIndex = 0;
            openFileDialog.RestoreDirectory = true;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                DataSet ds = null;
                DataTable dt = null;
                if (((dgv_result.DataSource as BindingSource) != null) && (((dgv_result.DataSource as BindingSource).DataSource as DataTable) != null))
                {
                    dt = ((dgv_result.DataSource as BindingSource).DataSource as DataTable);
                    ds = dt.DataSet;
                    dgv_result.DataSource = null;
                    dt.Dispose();
                }

                if (ds == null)
                {
                    ds = new DataSet();
                } 
                
                Stream myStream;
                if ((myStream = File.Open(openFileDialog.FileName, FileMode.Open)) != null)
                {
                    ds.ReadXml(myStream);
                    myStream.Close();
                }

                BindingSource bs = new BindingSource();
                dt = ds.Tables[0];
                bs.DataSource = dt;
                dgv_result.DataSource = bs;

                status.Text = string.Format("dataset loaded from file '{0}' with {1} processed file(s) and {2} items", openFileDialog.FileName, dt.Columns.Count > 3 ? dt.Columns.Count - 3 : 0, dt.Rows.Count);
            }
        }
        #endregion

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox a = new AboutBox();
            a.ShowDialog();
            a.Dispose();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //if (((dgv_result.DataSource as BindingSource) != null) && (((dgv_result.DataSource as BindingSource).DataSource as DataTable) != null))
            //{
                //Clipboard.SetData("System.Data.DataTable", ((dgv_result.DataSource as BindingSource).DataSource as DataTable));
                Clipboard.SetDataObject(dgv_result.GetClipboardContent(), true);
            //}
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            dgv_result.SelectAll();
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (OptionForm o = new OptionForm(new Options(Properties.Settings.Default.myOptions)))
            {
                if (o.ShowDialog() == DialogResult.OK)
                {
                    Properties.Settings.Default.myOptions = o._myOptions;
                    Properties.Settings.Default.Save();
                    DummyBusinessObject.opt = o._myOptions;
                    dgv_result.Invalidate();
                }
            }
        }

        private void test()
        {
            //test for importer1
            //string[] filenames  = new string[] { @".\..\..\_exampleFiles\v1\7350mk_13 (R11 1_2).txt", @".\..\..\_exampleFiles\v1\7350mk_14 (R11 1_3).txt" };

            //test for importer2
            string[] filenames = new string[] { 
                @".\..\..\_exampleFiles\\v2\\8024mk_1 wash.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_2 ctrl.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_3 ctrl.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_4 ctrl.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_5 ctrl.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_6 1c13.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_7 3c13.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_8 23c13.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_9 48c13.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_10 1c12.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_11 3c12.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_12 23c12.txt",
                @".\..\..\_exampleFiles\\v2\\8024mk_13 48c12.txt"            
            };
            
            progressBar.Value = 0;
            progressBar.Maximum = filenames.Length;

            button1.Text = "cancel";
            button1.Click -= new EventHandler(button1_Click_start);
            button1.Click += new EventHandler(button1_Click_cancel);

            Importer.BackgroundWorkerArgument bgwa = new Importer.BackgroundWorkerArgument { dt = null, filenames = filenames };
            //bgw_dispatcher.RunWorkerAsync(bgwa);
        }

        private void cbDisplay_SelectedIndexChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.myOptions.exportFact = (DisplayProperties) Enum.Parse(typeof(DisplayProperties), cbDisplay.Text);
            DummyBusinessObject.opt = Properties.Settings.Default.myOptions;
            dgv_result.Invalidate();
        }

        private void dgv_result_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {

            BusinessObject.Base bo = ((sender as DataGridView).Rows[e.RowIndex].DataBoundItem as DataRowView)[e.ColumnIndex] as BusinessObject.Base;
//            BusinessObject_2DAnalysis bo = ((sender as DataGridView)[e.ColumnIndex, e.RowIndex]..da) as BusinessObject_2DAnalysis;

            if (bo != null)
            {
                if (bo is BusinessObject.RetentionAnalysis)
                {
                    e.Value = (bo as BusinessObject.RetentionAnalysis).ValueNeeded();
                }
                else
                {
                    e.Value = (bo as BusinessObject.LibrarySearch).ValueNeeded();
                }
            }
        }
    }
}
